package db

import (
	"encoding/json"
	"fmt"
	config "funlog-gserver/config"
	"io"
	"log"
	"net/http"
	"strings"
	"sync"

	"github.com/elastic/go-elasticsearch/v7"
)

var ESClient *elasticsearch.Client
var once sync.Once

//InitES 初始化es
func InitES() {
	once.Do(func() {
		ESClient = openElasticsearchClien()
		resp, err := ESClient.Indices.PutIndexTemplate("funlog", strings.NewReader(fmt.Sprintf(`{
				"index_patterns" : [ "funlog*" ],
				"template": {
					"settings": {
						"index": {
							"highlight": {
								"max_analyzed_offset": "100000000"
							},
							"refresh_interval": "5s",
								"number_of_shards": "1",
								"number_of_replicas": "0"
						}
					},
					"mappings": {
						"properties": {
							"authInfo": {
								"type": "object",
								"dynamic":true,
								"properties":{
									"apikey":{
										"type":"text"
									},
									"ipAddr":{
										"type":"text"
									},
									"addr":{
										"type":"text"
									},
									"version":{
										"type":"text",
										"fields":{
											"keyword":{
												"ignore_above":256,
												"type":"keyword"
											}
										}
									},
									"env":{
										"type":"text"
									},
									"name":{
										"type":"text"
									},
									"sdkVersion":{
										"type":"text"
									},
									"trackerId":{
										"type":"text"
									},
									"sessionID":{
										"type":"text"
									},
									"uin":{
										"type":"text",
										"fields":{
											"keyword":{
												"ignore_above":256,
												"type":"keyword"
											}
										}
									},
									"os":{
										"type":"text",
										"fields":{
											"keyword":{
												"ignore_above":256,
												"type":"keyword"
											}
										}
									},
									"networkType":{
										"type":"text"
									},
									"browserInfo":{
										"type": "text",
										"fields":{
											"keyword":{
												"ignore_above":256,
												"type":"keyword"
											}
										}
									}
								}
							},
							"breadcrumb": {
								"type": "object",
								"dynamic":false
							},
							"data": {
								"dynamic":true,
								"type": "object",
								"properties":{
									"type":{
										"type":"text"
									},
									"message":{
										"type":"text"
									},
									"customTag":{
										"type":"text"
									},
									"time":{
										"type":"text"
									},
									"reportTime":{
										"type":"date"
									},
									"polymerizationUrl":{
										"type":"text",
										"fields":{
											"keyword":{
												"ignore_above":256,
												"type":"keyword"
											}
										}
									},
									"url":{
										"type":"text"
									},
									"stack":{
										"type": "object"
									},
									"ext":{
										"type": "object"
									},
									"ext1":{
										"type": "object"
									},
									"ext2":{
										"type": "object"
									},
									"errorId":{
										"type":"text"
									},
									"level":{
										"type":"text"
									}
								}
							}
						}
					},
					"aliases": {}
				}}`)))

		if err != nil {
			log.Printf("Error init funlog index template: %s", err)
		}
		defer resp.Body.Close()
		body, err := io.ReadAll(resp.Body)
		if err != nil {
			log.Printf("Error init funlog index template: %s", err)
		}
		if resp.IsError() {
			log.Printf("Init funlog index template failed, %s", string(body))
		}
		log.Printf("Init funlog index template success.")
	})
}

//openElasticsearchClien 获取一个es操作实例
func openElasticsearchClien() *elasticsearch.Client {
	h := config.Cnf["ES_ADDR"]
	if h == "" {
		log.Print("Invalid elasticseach host, please check the env config.")
		return nil
	}
	hosts := strings.Split(h, ";")
	cfg := elasticsearch.Config{
		Addresses: hosts,
		Transport: &http.Transport{
			MaxIdleConnsPerHost: 10,
		},
	}
	esClient, err := elasticsearch.NewClient(cfg)
	if err != nil {
		log.Printf("Error creating the elasticseach client: %s", err)
		return nil
	}

	res, err := esClient.Info()
	if err != nil {
		log.Printf("Error getting response: %s", err)
	}
	defer res.Body.Close()
	// Check response status
	if res.IsError() {
		log.Printf("Error: %s", res.String())
	}
	// Deserialize the response into a map.
	var r map[string]interface{}
	if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
		log.Printf("Error parsing the response body: %s", err)
	}
	// Print client and server version numbers.
	log.Printf("Elasticsearch client init success.")
	log.Printf("Client: %s", elasticsearch.Version)
	log.Printf("Server: %s", r["version"].(map[string]interface{})["number"])
	log.Println(strings.Repeat("=", 37))

	return esClient
}
